﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Security.Cryptography;
using System.IO;
using System.Data;
/// <summary>
/// Summary description for MyImage
/// </summary>
/// 
using CE.Database;

namespace CE.Image
{
    public class MyImage
    {
        public MyImage()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        // Reads the name of current web page
        public string GetMyName(string strScript)
        {
            // Get the script name
            //string strScript = Request.ServerVariables["SCRIPT_NAME"];

            // Get position of last slash
            int nPos = strScript.LastIndexOf("/");

            // Get everything after slash
            if (nPos > -1)
                strScript = strScript.Substring(nPos + 1);

            return strScript;
        }

        // Writes file to current folder
        public void WriteToFile(string strPath, ref byte[] Buffer)
        {
            // Create a file
            FileStream newFile = new FileStream(strPath, FileMode.Create);

            // Write data to the file
            newFile.Write(Buffer, 0, Buffer.Length);

            // Close file
            newFile.Close();
        }

        public static string ReadImageData(byte[] imageData, string filePath, string tmpImageName)
        {
            byte[] fileData = imageData;
            const int myBufferSize = 1024;
            string returnPath = String.Empty;
            try
            {
                Stream myInputStream = new MemoryStream(fileData);
                Stream myOutputStream = System.IO.File.OpenWrite(filePath);

                byte[] buffer = new Byte[myBufferSize];
                int numbytes;
                while ((numbytes = myInputStream.Read(buffer, 0, myBufferSize)) > 0)
                {
                    myOutputStream.Write(buffer, 0, numbytes);
                }
                myInputStream.Close();
                myOutputStream.Close();
                returnPath = "~/captcha/" + tmpImageName;
            }
            catch
            {
                returnPath = String.Empty;
            }

            return returnPath;
            #region Temp
            //Get image data from gridview column.
            //byte[] imageData = (byte[])dataGridView1.Rows[e.RowIndex].Cells["ImageData"].Value;

            //Initialize image variable
            /*Image newImage = null;

            try
            {
                //Read image data into a memory stream
                using (MemoryStream ms = new MemoryStream(ImageData, 0, ImageData.Length))
                {
                    ms.Write(ImageData, 0, ImageData.Length);

                    //Set image variable value using memory stream.
                    newImage = Image.FromStream(ms, true);
                }

                //set picture

            }
            catch (Exception ex)
            {

            }
            return newImage;*/
            #endregion
        }

        //Open file in to a filestream and read data in a byte array.
        public static byte[] ReadImageFile(string sPath, string uploadPath, int lWidth, int lHeight)
        {
            //Initialize byte array with a null value initially.
            byte[] data = null;

            //Use FileInfo object to get file size.
            FileInfo fInfo = new FileInfo(sPath);

            if (CheckExtension(fInfo.Extension))
            {
                //Create Temp Bitmap file to get width and height
                Bitmap bmp = new Bitmap(sPath);

                //For passing out parameter width and height
                float cWidth = 0.0f;
                float cHeight = 0.0f;
                //Create original image file for saving limit size
                System.Drawing.Image imgTmp = System.Drawing.Image.FromFile(sPath);
                //Change width and height not to over limited width and height
                //It also balance width and height ratio.
                ChangeLimitSize(bmp.Width, bmp.Height, lWidth, lHeight, out cWidth, out cHeight);
                //Create bitmap with limited size
                Bitmap bnew = new Bitmap(imgTmp, Convert.ToInt32(cWidth), Convert.ToInt32(cHeight));
                //Add Noise
                //bnew = Jitter(bnew, 50000);
                //Save image with limited size
                bnew.Save(uploadPath);
                //Clear bitmap file session
                bnew.Dispose();
                bmp.Dispose();
                bnew = null;
                bmp = null;

                long numBytes = fInfo.Length;

                //Open FileStream to read file
                FileStream fStream = new FileStream(uploadPath, FileMode.Open, FileAccess.Read);

                //Use BinaryReader to read file stream into byte array.
                BinaryReader br = new BinaryReader(fStream);

                //When you use BinaryReader, you need to supply number of bytes to read from file.
                //In this case we want to read entire file. So supplying total number of bytes.
                data = br.ReadBytes((int)numBytes);

                br.Close();
                fStream.Close();
            }
            return data;
        }

        public static void ChangeLimitSize(float oWidth, float oHeight, float lWidth, float lHeight, out float cWidth, out float cHeight)
        {
            float limitWidth = lWidth;
            float limitHeight = lHeight;
            float actualWidth = oWidth;
            float actualHeight = oHeight;
            float tempWidth = actualWidth;
            float tempHeight = actualHeight;

            while (tempWidth > limitWidth || tempHeight > limitHeight)
            {
                if (tempWidth > limitWidth)
                {
                    float currentWidth = tempWidth;
                    float byPercent = 0.0f;
                    tempWidth = tempWidth - limitWidth;
                    byPercent = (tempWidth / currentWidth);
                    byPercent = 1 - byPercent;
                    tempWidth = lWidth;
                    tempHeight = tempHeight * byPercent;
                }
                else if (tempHeight > limitHeight)
                {
                    float currentHeight = tempHeight;
                    float byPercent = 0.0f;
                    tempHeight = tempHeight - limitHeight;
                    byPercent = (tempHeight / currentHeight);
                    byPercent = 1 - byPercent;
                    tempWidth = tempWidth * byPercent;
                    tempHeight = lHeight;
                }
            }
            cWidth = tempWidth;
            cHeight = tempHeight;

        }

        private static bool CheckExtension(string Extension)
        {
            string[] extList = { ".jpg", ".gif", ".jpeg", ".png", ".bmp" };
            bool isInList = false;
            for (int i = 0; i < extList.Length; i++)
            {
                if (Extension.ToLower() == extList[i])
                {
                    isInList = true;
                }
                break;
            }
            return isInList;
        }

        public string CreateRandomImage(string Path, int width, int height)
        {
            Random r = new Random();
            string salt = CreateSalt(4);
            salt = salt.Substring(0, 6);
            salt = salt.Replace('+', 'Z');
            salt = salt.Replace('-', 'Y');
            salt = salt.Replace('*', 'X');
            salt = salt.Replace('/', 'V');

            #region Comment
            /*
            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(bmp);
            g.TextRenderingHint = TextRenderingHint.AntiAlias;
            g.Clear(Color.Gray);
            g.DrawRectangle(Pens.White, 1, 1, width - 3, height - 3);
            g.DrawRectangle(Pens.Black, 0, 0, width, height);
            System.Drawing.Drawing2D.Matrix mymat = new System.Drawing.Drawing2D.Matrix();

            for (int i = 0; i < salt.Length; i++)
            {
                mymat.Reset();
                float w = Convert.ToSingle(width * (0.12 * i));
                float h = Convert.ToSingle(height);
                mymat.RotateAt(r.Next(-30, 0), new PointF(w, h * 0.5f));
                g.Transform = mymat;
                g.DrawString(salt[i].ToString(), new Font("Comic Sans MS", 35, FontStyle.Italic), Brushes.AliceBlue, w, h * 0.3f);
                g.ResetTransform();
            }

            using (MemoryStream stream = new MemoryStream())
            {
                bmp.Save(stream, ImageFormat.Gif);
                mStream = stream;
            }

            //bmp.Save(Path, ImageFormat.Gif);
            g.Dispose();
            bmp.Dispose();
            */
            #endregion

            return salt;
        }

        public string CreateSalt(int size)
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            Byte[] buff = new Byte[size];
            rng.GetBytes(buff);

            return Convert.ToBase64String(buff);
        }

        public string GetRandomWord(string strCurrentWord)
        {
            MyDatabase _myDb = new MyDatabase();
            DataTable _dtCaptcha = new DataTable("tblCAPTCHA");
            _dtCaptcha = _myDb.GetDataTable("select top 1 * from tblCaptcha Where Word <> '"+ strCurrentWord +"' And (Len(Word) > 4 And  Len(Word) < 9) And Status = 1 Order by newid()");
            string _retValue = "";

            if (_dtCaptcha != null)
            {
                if (_dtCaptcha.Rows.Count > 0)
                    _retValue = _dtCaptcha.Rows[0][1].ToString();
            }
            else
            {
                _retValue = "NO IMAGE";
            }
            //To change Upper case for eventh character
            //string _retTempValue = "";
            //for (int i = 0; i < _retValue.Length; i++)
            //{
            //    if (i % 2 == 0)
            //    {
            //        _retTempValue += _retValue[i].ToString().ToUpper();
            //    }
            //    else
            //    {
            //        _retTempValue += _retValue[i].ToString().ToLower();
            //    }
            //}
            //_retValue = _retTempValue;

            return _retValue; ;
        }

        public static Bitmap AddNoise(Bitmap Image, int Amount)
        {
            System.Drawing.Bitmap TempBitmap = Image;
            System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height);
            System.Drawing.Graphics NewGraphics = System.Drawing.Graphics.FromImage(NewBitmap);
            NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), System.Drawing.GraphicsUnit.Pixel);
            NewGraphics.Dispose();
            Random TempRandom = new Random();
            for (int x = 0; x < NewBitmap.Width; ++x)
            {
                for (int y = 0; y < NewBitmap.Height; ++y)
                {
                    Color CurrentPixel = TempBitmap.GetPixel(x, y);
                    int R = CurrentPixel.R + TempRandom.Next(-Amount, Amount + 1);
                    int G = CurrentPixel.G + TempRandom.Next(-Amount, Amount + 1);
                    int B = CurrentPixel.B + TempRandom.Next(-Amount, Amount + 1);
                    R = R > 255 ? 255 : R;
                    R = R < 0 ? 0 : R;
                    G = G > 255 ? 255 : G;
                    G = G < 0 ? 0 : G;
                    B = B > 255 ? 255 : B;
                    B = B < 0 ? 0 : B;
                    Color TempValue = Color.FromArgb(R, G, B);
                    NewBitmap.SetPixel(x, y, TempValue);
                }
            }
            return NewBitmap;
        }

        public static Bitmap Jitter(Bitmap Image, int MaxJitter)
        {
            System.Drawing.Bitmap TempBitmap = Image;
            System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height);
            System.Drawing.Graphics NewGraphics = System.Drawing.Graphics.FromImage(NewBitmap);
            NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), System.Drawing.GraphicsUnit.Pixel);
            NewGraphics.Dispose();
            Random TempRandom = new Random();
            for (int x = 0; x < NewBitmap.Width; ++x)
            {
                for (int y = 0; y < NewBitmap.Height; ++y)
                {
                    int NewX = TempRandom.Next(-MaxJitter, MaxJitter);
                    int NewY = TempRandom.Next(-MaxJitter, MaxJitter);
                    NewX += x;
                    NewY += y;

                    if (NewX >= NewBitmap.Width)
                        NewX = NewBitmap.Width - 1;
                    else if (NewX < 0)
                        NewX = 0;

                    if (NewY >= NewBitmap.Height)
                        NewY = NewBitmap.Height - 1;
                    else if (NewY < 0)
                        NewY = 0;

                    NewBitmap.SetPixel(NewX, NewY, Image.GetPixel(x, y));
                }
            }
            return NewBitmap;
        } 
    }
}